package com.fingard.dsp.bank.directbank.fngrd01;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fingard.constant.Format;
import com.fingard.dsp.bank.directConfig.ActSetItem;
import com.fingard.dsp.bank.directbank.FailCode;
import com.fingard.dsp.bank.directbank.PaymentState;
import com.fingard.dsp.bank.directbank.bankInterface.ISinglePay;
import com.fingard.dsp.bank.reqrespobj.single.*;
import com.fingard.dsp.bank.reqrespobj.single.detail.RetAtsSglDetail;
import com.fingard.net.ConnState;
import com.fingard.text.StringHelper;
import com.fingard.xml.XElement;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

import java.util.HashMap;

public class FnGrd01SinglePay extends FnGrd01Base implements ISinglePay {
    @Override
    public RetAtsSingle d_1908_SglPay(ReqSingle p_req1908) throws Exception {
        RetAtsSingle retAts = new RetAtsSingle(p_req1908.reqHeader);
        RetAtsSglDetail tmpRetDetail = new RetAtsSglDetail();

        if ("190806".equals(p_req1908.reqHeader.commandCode)) {
            tmpRetDetail = d_190806(p_req1908);
        } else if ("1908".equals(p_req1908.reqHeader.transType) && "690803".equals(p_req1908.reqHeader.commandCode)) {
            tmpRetDetail = d_190803(p_req1908);
        } else {
            tmpRetDetail = d_190802(p_req1908);
        }

        if (tmpRetDetail.respCode.equals("-1") && StringHelper.isNullOrEmpty(tmpRetDetail.reqSeqID)) {
            tmpRetDetail.reqSeqID = p_req1908.singleDetail.askNumber;
        }

        retAts.writeRetDetail(tmpRetDetail);
        return retAts;
    }

    private RetAtsSglDetail d_190802(ReqSingle p_req1908) throws Exception {
        RetAtsSglDetail tmpRetDetail = new RetAtsSglDetail();

        try {
            FnGrd01Header bankHeader = new FnGrd01Header();

            if ("690801".equals(p_req1908.reqHeader.commandCode) || "190801".equals(p_req1908.reqHeader.commandCode)) {
                bankHeader.CommandCode = "10121";
            } else if ("690802".equals(p_req1908.reqHeader.commandCode) || "190802".equals(p_req1908.reqHeader.commandCode)) {
                bankHeader.CommandCode = "11121";
            }

            bankHeader.CorpBankCode = getBankConfig().getMapValueByKey("corBankCodeMapping", p_req1908.singleDetail.payAct);
            if (StringHelper.isNullOrEmpty(bankHeader.CorpBankCode)) {
                WriteBankLogLn2("CorpBankCode为空，请配置corBankCodeMapping映射");
            }

            bankHeader.TransSeqID = getQryTransID();

            XmlTextWriter xmlWriter = new XmlTextWriter();
            writeRealTimeCommonHeader(xmlWriter, bankHeader);

            xmlWriter.writeStartElement("RealTimeSingleTransReq");
            xmlWriter.writeElementString("MoneyWay", "1".equals(p_req1908.singleDetail.sameBnk) ? "1" : "7");
            xmlWriter.writeElementString("TransDate", p_req1908.singleDetail.payDate.replace("-", ""));

            // 需要进行对账码拼接以及节点解析，采用XElement进行处理
            XElement tmpXElement = new XElement("Trans", "");

            tmpXElement.addChild(new XElement("TransNo", p_req1908.singleDetail.askNumber));
            tmpXElement.addChild(new XElement("ProtocolCode", p_req1908.singleDetail.recAct));
            tmpXElement.addChild(new XElement("EnterpriseAccNum", p_req1908.singleDetail.payAct));
            tmpXElement.addChild(new XElement("CustBankCode", p_req1908.singleDetail.recBankCode));
            tmpXElement.addChild(new XElement("CustAccNum", p_req1908.singleDetail.recAct));
            tmpXElement.addChild(new XElement("CustAccName", p_req1908.singleDetail.recName));
            tmpXElement.addChild(new XElement("AreaCode", p_req1908.singleDetail.recArea));
            tmpXElement.addChild(new XElement("BankLocationCode", p_req1908.singleDetail.cnapsCode));
            String cnapsName = p_req1908.singleDetail.payBankLocation;
            if (StringHelper.isNullOrEmpty(cnapsName)) {
                cnapsName = p_req1908.singleDetail.cnapsName;
            }
            tmpXElement.addChild(new XElement("BankLocationName", cnapsName));

            // 卡折标记 0卡;1折
            if (p_req1908.singleDetail.cardType != null && p_req1908.singleDetail.cardType.equals("1")) {
                tmpXElement.addChild(new XElement("CardType", "1"));
            } else {
                tmpXElement.addChild(new XElement("CardType", "0"));
            }

            // 0：私人 1：公司
            if (p_req1908.singleDetail.isPrivate.equals("1")) {
                tmpXElement.addChild(new XElement("IsPrivate", "0"));
            } else {
                tmpXElement.addChild(new XElement("IsPrivate", "1"));
            }

            tmpXElement.addChild(new XElement("IsUrgent", ""));
            tmpXElement.addChild(new XElement("Amount", p_req1908.singleDetail.payAmount));
            tmpXElement.addChild(new XElement("Currency", convertCurToBank(p_req1908.singleDetail.recCur)));
            tmpXElement.addChild(new XElement("CertType", convertCertTypeToBank(p_req1908.singleDetail.certType)));
            tmpXElement.addChild(new XElement("CertNum", p_req1908.singleDetail.certNum));
            tmpXElement.addChild(new XElement("Mobile", ""));
            tmpXElement.addChild(new XElement("Purpose", p_req1908.singleDetail.purpose));
            tmpXElement.addChild(new XElement("Memo", p_req1908.singleDetail.memo));
            tmpXElement.addChild(new XElement("ReconciliationCode", p_req1908.singleDetail.abstractATS));
            tmpXElement.addChild(new XElement("Extent1", ""));
            tmpXElement.addChild(new XElement("Extent2", ""));
            nodeAnalysis(p_req1908.singleDetail.srcXElement, tmpXElement, getCharset());
            xmlWriter.writeXElement(tmpXElement);

            xmlWriter.writeEndDocument();

            String[] tmpStrRet = sendToBank(xmlWriter.toXmlString());

            if (tmpStrRet[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);

                if (tmpBkReader != null) {
                    String tmpRetCode = tmpBkReader.getFirstText("/Root/Head/RespCode");
                    String tmpRetMsg = tmpBkReader.getFirstText("/Root/Head/RespInfo");

                    int tmpIntRespCode = -1;
                    if (StringHelper.hasAnyChar(tmpRetCode)) {
                        tmpIntRespCode = Integer.parseInt(tmpRetCode);

                        tmpRetDetail.respCode = "0";
                        tmpRetDetail.reqSeqID = p_req1908.singleDetail.askNumber;

                        if (tmpIntRespCode >= 0) {
                            tmpRetDetail.respInfo = tmpBkReader.getFirstText("/Root/RealTimeSingleTransResp/Trans/Info");
                            tmpRetDetail.transState = tmpBkReader.getFirstText("/Root/RealTimeSingleTransResp/Trans/State");
                            tmpRetDetail.payInfoCode = tmpBkReader.getFirstText("/Root/RealTimeSingleTransResp/Trans/InfoCode");
                            tmpRetDetail.transAmt = tmpBkReader.getFirstText("/Root/RealTimeSingleTransResp/Trans/Amount");
                        } else {
                            tmpRetDetail.respCode = "-1";
                            if (StringHelper.isNullOrEmpty(tmpRetMsg)) {
                                tmpRetDetail.respInfo = "前置返回查询失败RespCode：" + tmpRetCode;
                            } else {
                                tmpRetDetail.respInfo = tmpRetMsg;
                                if (tmpRetMsg.contains("处理中")) {
                                    tmpRetDetail.respCode = "0";
                                    tmpRetDetail.transState = "4";
                                    tmpRetDetail.payInfoCode = "I4001";
                                }
                            }
                        }
                    }
                } else {
                    tmpRetDetail.respCode = "-1";
                    tmpRetDetail.respInfo = tmpSbMsg.toString();
                }
            } else if (tmpStrRet[0].equals(ConnState.FAIL)) {
                tmpRetDetail.respCode = "0";
                tmpRetDetail.respInfo = tmpStrRet[1];
                tmpRetDetail.reqSeqID = p_req1908.singleDetail.askNumber;
                tmpRetDetail.transState = PaymentState.FAIL_Payment;
                tmpRetDetail.payInfoCode = FailCode.E9999;
            } else {
                tmpRetDetail.respCode = "-1";
                tmpRetDetail.respInfo = tmpStrRet[1];
            }
        } catch (Exception ex) {
            ex.printStackTrace();

            tmpRetDetail.respCode = "-1";
            tmpRetDetail.respInfo = ex.getMessage();

            WriteBankLogLn(ex);
        }

        return tmpRetDetail;
    }

    private RetAtsSglDetail d_190803(ReqSingle p_req1908) throws Exception {
        RetAtsSglDetail tmpRetDetail = new RetAtsSglDetail();

        try {
            FnGrd01Header bankHeader = new FnGrd01Header();
            bankHeader.CommandCode = "12128";
            bankHeader.CorpBankCode = getBankConfig().getMapValueByKey("corBankCodeMapping", p_req1908.singleDetail.payAct);
            if (StringHelper.isNullOrEmpty(bankHeader.CorpBankCode)) {
                WriteBankLogLn2("CorpBankCode为空，请配置corBankCodeMapping映射");
            }
            bankHeader.TransSeqID = getQryTransID();

            XmlTextWriter xmlWriter = new XmlTextWriter();
            writeRealTimeCommonHeader(xmlWriter, bankHeader);

            xmlWriter.writeStartElement("RealTimeSingleTransReq");
            xmlWriter.writeElementString("MoneyWay", "3");
            xmlWriter.writeElementString("TransDate", p_req1908.singleDetail.payDate.replace("-", ""));
            XElement tmpXElement = new XElement("Trans", "");
            tmpXElement.addChild(new XElement("TransNo", p_req1908.singleDetail.askNumber));
            String[] authCodeSp = p_req1908.singleDetail.authCode.split("__");
            String protocolCode = authCodeSp[0];
            tmpXElement.addChild(new XElement("ProtocolCode", protocolCode));
            tmpXElement.addChild(new XElement("EnterpriseAccNum", p_req1908.singleDetail.payAct));
            tmpXElement.addChild(new XElement("CustBankCode", p_req1908.singleDetail.recBankCode));
            tmpXElement.addChild(new XElement("CustAccNum", p_req1908.singleDetail.recAct));
            tmpXElement.addChild(new XElement("CustAccName", p_req1908.singleDetail.recName));
            tmpXElement.addChild(new XElement("AreaCode", p_req1908.singleDetail.recArea));
            tmpXElement.addChild(new XElement("BankLocationCode", p_req1908.singleDetail.cnapsCode));
            tmpXElement.addChild(new XElement("BankLocationName", p_req1908.singleDetail.recBankLocation));
            //卡折标记0卡;1折
            if (p_req1908.singleDetail.cardType != null && p_req1908.singleDetail.cardType.equals("1")) {
                tmpXElement.addChild(new XElement("CardType", "1"));
            } else {
                tmpXElement.addChild(new XElement("CardType", "0"));
            }

            if (p_req1908.singleDetail.isPrivate.equals("1")) {//0：私人   1：公司
                tmpXElement.addChild(new XElement("IsPrivate", "0"));
            } else {
                tmpXElement.addChild(new XElement("IsPrivate", "1"));
            }
            tmpXElement.addChild(new XElement("IsUrgent", ""));
            tmpXElement.addChild(new XElement("Amount", p_req1908.singleDetail.payAmount));
            tmpXElement.addChild(new XElement("Currency", convertCurToBank(p_req1908.singleDetail.recCur)));
            tmpXElement.addChild(new XElement("CertType", convertCertTypeToBank(p_req1908.singleDetail.certType)));
            tmpXElement.addChild(new XElement("CertNum", p_req1908.singleDetail.certNum));
            tmpXElement.addChild(new XElement("Mobile", ""));
            tmpXElement.addChild(new XElement("ReconciliationCode", p_req1908.singleDetail.abstractATS));
            tmpXElement.addChild(new XElement("Purpose", p_req1908.singleDetail.purpose));
            tmpXElement.addChild(new XElement("Memo", p_req1908.singleDetail.memo));
            tmpXElement.addChild(new XElement("ORGCode", p_req1908.singleDetail.orgCode));
            tmpXElement.addChild((new XElement("PolicyNumber", p_req1908.singleDetail.insuPolicyNum)));//投保单号
            tmpXElement.addChild((new XElement("SourceNote", p_req1908.singleDetail.sourceNote)));//保单号
            tmpXElement.addChild(new XElement("Extent1", ""));
            tmpXElement.addChild(new XElement("Extent2", ""));
            nodeAnalysis(p_req1908.singleDetail.srcXElement, tmpXElement, getCharset());
            xmlWriter.writeXElement(tmpXElement);
            xmlWriter.writeEndDocument();

            String[] tmpStrRet = sendToBank(xmlWriter.toXmlString());
            if (tmpStrRet[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String tmpRetCode = tmpBkReader.getFirstText("/Root/Head/RespCode");
                    String tmpRetMsg = tmpBkReader.getFirstText("/Root/Head/RespInfo");
                    int tmpIntRespCode = -1;
                    if (!StringHelper.isNullOrEmpty(tmpRetCode)) {
                        tmpIntRespCode = Integer.parseInt(tmpRetCode);
                    }
                    tmpRetDetail.respCode = "0";
                    if (tmpIntRespCode >= 0 || (tmpIntRespCode < 0 && "103".equals(bankHeader.CorpBankCode))) {
                        String transStatus = tmpBkReader.getFirstText("/Root/RealTimeSingleTransResp/Trans/State");
                        if ("4".equals(transStatus) && "103".equals(bankHeader.CorpBankCode) || tmpRetMsg.contains("处理中")) {
                            long realSleepTime = getBankConfig().getValueAsInt("realSleepTime");
                            Thread.sleep(realSleepTime * 1000);

                            bankHeader.CommandCode = "22128";
                            bankHeader.TransSeqID = getQryTransID();

                            xmlWriter = new XmlTextWriter();//发银行报文的XML对象
                            writeCommonHeader(xmlWriter, bankHeader);
                            xmlWriter.writeStartElement("RealTimeSingleTransQueryReq");
                            xmlWriter.writeElementString("TransNo", p_req1908.singleDetail.askNumber);
                            xmlWriter.writeElementString("TransDate", Format.Date8Format.format(p_req1908.singleDetail.getPayDateTime()));
                            xmlWriter.writeEndDocument();

                            tmpStrRet = sendToBank(xmlWriter.toXmlString());

                            if (tmpStrRet[0].length() == 0) {
                                tmpSbMsg = new StringBuilder();
                                tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                                if (tmpBkReader != null) {
                                    tmpRetCode = tmpBkReader.getFirstText("/Root/Head/RespCode");
                                    tmpRetMsg = tmpBkReader.getFirstText("/Root/Head/RespInfo");
                                    if (!StringHelper.isNullOrEmpty(tmpRetCode)) {
                                        tmpIntRespCode = Integer.parseInt(tmpRetCode);
                                    }
                                    tmpRetDetail.respCode = "0";

                                    if (tmpIntRespCode >= 0) {
                                        tmpRetDetail.reqSeqID = tmpBkReader.getFirstText("/Root/RealTimeSingleTransQueryResp/Trans/TransNo");
                                        tmpRetDetail.respInfo = tmpBkReader.getFirstText("/Root/RealTimeSingleTransQueryResp/Trans/Info");
                                        tmpRetDetail.transState = tmpBkReader.getFirstText("/Root/RealTimeSingleTransQueryResp/Trans/State");
                                        tmpRetDetail.payInfoCode = tmpBkReader.getFirstText("/Root/RealTimeSingleTransQueryResp/Trans/InfoCode");
                                        tmpRetDetail.transAmt = tmpBkReader.getFirstText("/Root/RealTimeSingleTransQueryResp/Trans/Amount");
                                    } else {
                                        tmpRetDetail.respCode = "-1";
                                        if (StringHelper.isNullOrEmpty(tmpRetMsg)) {
                                            tmpRetDetail.respInfo = "前置返回查询失败RespCode：" + tmpRetCode;
                                        } else {
                                            tmpRetDetail.respInfo = tmpRetMsg;
                                            if (tmpRetMsg.contains("处理中")) {
                                                tmpRetDetail.respCode = "0";
                                                tmpRetDetail.transState = "4";
                                                tmpRetDetail.payInfoCode = "I4001";
                                            }
                                        }
                                    }
                                } else {
                                    tmpRetDetail.respCode = "-1";
                                    tmpRetDetail.respInfo = tmpSbMsg.toString();
                                }
                            } else {
                                tmpRetDetail.respCode = "-1";
                                tmpRetDetail.respInfo = tmpStrRet[1];
                            }
                        } else {
                            tmpRetDetail.reqSeqID = tmpBkReader.getFirstText("/Root/RealTimeSingleTransResp/Trans/TransNo");
                            tmpRetDetail.respInfo = tmpBkReader.getFirstText("/Root/RealTimeSingleTransResp/Trans/Info");
                            tmpRetDetail.transState = tmpBkReader.getFirstText("/Root/RealTimeSingleTransResp/Trans/State");
                            tmpRetDetail.payInfoCode = tmpBkReader.getFirstText("/Root/RealTimeSingleTransResp/Trans/InfoCode");
                            tmpRetDetail.transAmt = tmpBkReader.getFirstText("/Root/RealTimeSingleTransResp/Trans/Amount");
                        }
                    } else {
                        tmpRetDetail.respCode = "-1";
                        if (StringHelper.isNullOrEmpty(tmpRetMsg)) {
                            tmpRetDetail.respInfo = "前置返回查询失败RespCode：" + tmpRetCode;
                        } else {
                            tmpRetDetail.respInfo = tmpRetMsg;
                            if (tmpRetMsg.contains("处理中")) {
                                tmpRetDetail.respCode = "0";
                                tmpRetDetail.transState = "4";
                                tmpRetDetail.payInfoCode = "I4001";
                            }
                        }
                    }
                } else {
                    tmpRetDetail.respCode = "-1";
                    tmpRetDetail.respInfo = tmpSbMsg.toString();
                }
            } else if (tmpStrRet[0].equals(ConnState.FAIL)) {
                tmpRetDetail.respCode = "0";
                tmpRetDetail.respInfo = tmpStrRet[1];
                tmpRetDetail.reqSeqID = p_req1908.singleDetail.askNumber;
                tmpRetDetail.transState = PaymentState.FAIL_Payment;
                tmpRetDetail.payInfoCode = tmpStrRet[0];
            } else {
                tmpRetDetail.respCode = "-1";
                tmpRetDetail.respInfo = tmpStrRet[1];
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            tmpRetDetail.respCode = "-1";
            tmpRetDetail.respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }
        return tmpRetDetail;
    }

    /**
     * 扫码付退款提交
     *
     * @param p_req1908
     * @return
     * @throws Exception
     */
    private RetAtsSglDetail d_190806(ReqSingle p_req1908) throws Exception {
        RetAtsSglDetail tmpRetDetail = new RetAtsSglDetail();

        try {
            ActSetItem actItem = getBankConfig().getActSetItem(p_req1908.singleDetail.payAct, "unifiedorder");
            if (actItem != null) {
                HashMap<String, String> mapParams = new HashMap<String, String>();

                mapParams.put("EnterpriseNum", actItem.inMerchantId);
                mapParams.put("MchId", actItem.merchantId);
                mapParams.put("OutTradeNo", p_req1908.singleDetail.askNumber);
                mapParams.put("FGTradeNo", "");
                mapParams.put("RefundNo", p_req1908.singleDetail.recAct);
                mapParams.put("TotalFee", StringHelper.amountMultiply100(p_req1908.singleDetail.payAmount));
                mapParams.put("RefundFee", StringHelper.amountMultiply100(p_req1908.singleDetail.payAmount));
                mapParams.put("RefundChannel", "ORIGINAL"); /* ORIGINAL-原路退款，默认 */
                mapParams.put("NonceStr", get_nonce_str());

                // 签名
                String signStr = getSignStr(mapParams, actItem.saltKey);
                String signature = signFnGrd(actItem, signStr);

                mapParams.put("Signature", signature);

                // post请求数据
                String reqPostJson = getReqPostJson(mapParams);
                String reqSendData = getReqSendData(actItem.inMerchantId, reqPostJson);

                String url = bankFront.getUrl("QRPayRefundSubmit");

                // 发融汇
                String[] tmpStrRet = sendToFnGrd(reqSendData, url);

                if (tmpStrRet[0].length() == 0) {
                    if (tmpStrRet[1].indexOf("Status") > 0) {
                        JSONObject respJSON = JSON.parseObject(tmpStrRet[1]);

                        String status = respJSON.getString("Status");
                        if ("-1".equals(status)) {
                            tmpRetDetail.respCode = "-1";
                            tmpRetDetail.respInfo = respJSON.getString("ReturnMsg");

                            return tmpRetDetail;
                        }
                    } else {
                        String tmpStrResp = getRespPostData(tmpStrRet[1]);
                        JSONObject respJSONObj = JSON.parseObject(tmpStrResp);

                        tmpRetDetail.respCode = "0";
                        tmpRetDetail.respInfo = respJSONObj.getString("ReturnMsg");

                        tmpRetDetail.reqSeqID = respJSONObj.getString("OutTradeNo");
                        if (StringHelper.isNullOrEmpty(tmpRetDetail.reqSeqID)) {
                            tmpRetDetail.reqSeqID = p_req1908.singleDetail.askNumber;
                        }

                        String status = respJSONObj.getString("Status");
                        if ("0".equals(status)) {
                            tmpRetDetail.transAmt = StringHelper.amountDivide100(respJSONObj.getString("RefundFee"));
                        }

                        tmpRetDetail.transState = status;
                        tmpRetDetail.payInfoCode = status;
                    }
                } else if (tmpStrRet[0].equals(ConnState.FAIL)) {
                    tmpRetDetail.respCode = "0";
                    tmpRetDetail.respInfo = tmpStrRet[1];
                    tmpRetDetail.reqSeqID = p_req1908.singleDetail.askNumber;
                    tmpRetDetail.transState = PaymentState.FAIL_Payment;
                    tmpRetDetail.payInfoCode = FailCode.E9999;
                } else {
                    tmpRetDetail.respCode = "-1";
                    tmpRetDetail.respInfo = tmpStrRet[1];
                }
            } else {
                tmpRetDetail.respCode = "0";
                tmpRetDetail.respInfo = "未找到账号: --[" + p_req1908.singleDetail.payAct + "]-- 商户信息";
                tmpRetDetail.reqSeqID = p_req1908.singleDetail.askNumber;
                tmpRetDetail.transState = PaymentState.FAIL_Payment;
                tmpRetDetail.payInfoCode = FailCode.E9981;
            }
        } catch (Exception ex) {
            ex.printStackTrace();

            tmpRetDetail.respCode = "-1";
            tmpRetDetail.respInfo = ex.getMessage();

            WriteBankLogLn(ex);
        }

        if (StringHelper.isNullOrEmpty(tmpRetDetail.reqSeqID) && "-1".equals(tmpRetDetail.respCode)) {
            tmpRetDetail.reqSeqID = p_req1908.singleDetail.askNumber;
        }

        return tmpRetDetail;
    }

    @Override
    public RetAtsSingle d_1944_QrySglPay(ReqQrySingle p_req1944) throws Exception {
        RetAtsSingle retAts = new RetAtsSingle(p_req1944.reqHeader);
        RetAtsSglDetail tmpRetDetail = new RetAtsSglDetail();

        try {
            if ("190806".equals(p_req1944.reqHeader.commandCode)) {
                retAts = d_190806_QrySglPay(p_req1944); // 退款
                return retAts;
            }
            if ("690803".equals(p_req1944.reqHeader.commandCode)) {
                retAts = d_190803_QrySglPay(p_req1944); // 退款
                return retAts;
            }

            FnGrd01Header bankHeader = new FnGrd01Header();

            bankHeader.CommandCode = "20121";

            bankHeader.CorpBankCode = getBankConfig().getMapValueByKey("corBankCodeMapping", p_req1944.payAct);
            if (StringHelper.isNullOrEmpty(bankHeader.CorpBankCode)) {
                WriteBankLogLn2("CorpBankCode为空，请配置corBankCodeMapping映射");
            }

            bankHeader.TransSeqID = getQryTransID();
            bankHeader.SourceChannel = "ATS01";

            XmlTextWriter xmlWriter = new XmlTextWriter();
            writeCommonHeader(xmlWriter, bankHeader);

            xmlWriter.writeStartElement("RealTimeSingleTransQueryReq");
            xmlWriter.writeElementString("TransNo", p_req1944.askNumber);
            xmlWriter.writeElementString("TransDate", Format.Date8Format.format(p_req1944.getBgnDateTime()));
            xmlWriter.writeEndDocument();

            String[] tmpStrRet = sendToBank(xmlWriter.toXmlString());

            if (tmpStrRet[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String tmpRetCode = tmpBkReader.getFirstText("/Root/Head/RespCode");
                    String tmpRetMsg = tmpBkReader.getFirstText("/Root/Head/RespInfo");
                    int tmpIntRespCode = -1;
                    if (!StringHelper.isNullOrEmpty(tmpRetCode)) {
                        tmpIntRespCode = Integer.parseInt(tmpRetCode);
                    }
                    if (tmpIntRespCode >= 0) {
                        tmpRetDetail.respCode = "0";
                        tmpRetDetail.reqSeqID = tmpBkReader.getFirstText("/Root/RealTimeSingleTransQueryResp/Trans/TransNo");
                        tmpRetDetail.respInfo = tmpBkReader.getFirstText("/Root/RealTimeSingleTransQueryResp/Trans/Info");
                        tmpRetDetail.transState = tmpBkReader.getFirstText("/Root/RealTimeSingleTransQueryResp/Trans/State");
                        tmpRetDetail.payInfoCode = tmpBkReader.getFirstText("/Root/RealTimeSingleTransQueryResp/Trans/InfoCode");
                        tmpRetDetail.transAmt = tmpBkReader.getFirstText("/Root/RealTimeSingleTransQueryResp/Trans/Amount");
                    } else {
                        tmpRetDetail.respCode = "-1";
                        if (StringHelper.isNullOrEmpty(tmpRetMsg)) {
                            tmpRetDetail.respInfo = "前置返回查询失败RespCode：" + tmpRetCode;
                        } else {
                            tmpRetDetail.respInfo = tmpRetMsg;
                        }
                    }
                } else {
                    tmpRetDetail.respCode = "-1";
                    tmpRetDetail.respInfo = tmpSbMsg.toString();
                }
            } else {
                tmpRetDetail.respCode = "-1";
                tmpRetDetail.respInfo = tmpStrRet[1];
            }
        } catch (Exception ex) {
            ex.printStackTrace();

            tmpRetDetail.respCode = "-1";
            tmpRetDetail.respInfo = ex.getMessage();

            WriteBankLogLn(ex);
        }

        if ("-1".equals(tmpRetDetail.respCode) && StringHelper.isNullOrEmpty(tmpRetDetail.reqSeqID)) {
            tmpRetDetail.reqSeqID = p_req1944.askNumber;
        }

        retAts.writeRetDetail(tmpRetDetail);
        return retAts;
    }

    /**
     * 扫码付退款查询
     *
     * @param p_req1944
     * @return
     * @throws Exception
     */
    public RetAtsSingle d_190806_QrySglPay(ReqQrySingle p_req1944) throws Exception {
        RetAtsSingle retAts = new RetAtsSingle(p_req1944.reqHeader);
        RetAtsSglDetail tmpRetDetail = new RetAtsSglDetail();

        try {
            ActSetItem actItem = getBankConfig().getActSetItem(p_req1944.payAct, "unifiedorder");
            if (actItem != null) {
                HashMap<String, String> mapParams = new HashMap<String, String>();

                mapParams.put("EnterpriseNum", actItem.inMerchantId);
                mapParams.put("MchId", actItem.merchantId);
                mapParams.put("OutTradeNo", p_req1944.askNumber);
                mapParams.put("FGTradeNo", "");
                mapParams.put("RefundNo", p_req1944.recAct);
                mapParams.put("FGRefundNo", "");
                mapParams.put("NonceStr", get_nonce_str());

                // 签名
                String signStr = getSignStr(mapParams, actItem.saltKey);
                String signature = signFnGrd(actItem, signStr);

                mapParams.put("Signature", signature);

                // post请求数据
                String reqPostJson = getReqPostJson(mapParams);
                String reqSendData = getReqSendData(actItem.inMerchantId, reqPostJson);

                String url = bankFront.getUrl("QRPayRefundQuery");

                // 发融汇
                String[] tmpStrRet = sendToFnGrd(reqSendData, url);

                if (tmpStrRet[0].length() == 0) {
                    if (tmpStrRet[1].indexOf("Status") > 0) {
                        JSONObject respJSON = JSON.parseObject(tmpStrRet[1]);

                        String status = respJSON.getString("Status");
                        if ("-1".equals(status)) {
                            retAts.writeRespCode("-1");
                            retAts.writeRespInfo(respJSON.getString("ReturnMsg"));

                            return retAts;
                        }
                    } else {
                        String tmpStrResp = getRespPostData(tmpStrRet[1]);
                        JSONObject respJSONObj = JSON.parseObject(tmpStrResp);

                        String status = respJSONObj.getString("Status");
                        if ("0".equals(status)) {
                            // 目前退款为单笔退款，所以只有一笔交易，退款笔数为1
                            int refundCount = Integer.parseInt(respJSONObj.getString("RefundCount"));
                            for (int i = 0; i < refundCount; i++) {
                                tmpRetDetail.respCode = "0";
                                tmpRetDetail.respInfo = respJSONObj.getString("ReturnMsg");

                                tmpRetDetail.reqSeqID = respJSONObj.getString("OutTradeNo");
                                if (StringHelper.isNullOrEmpty(tmpRetDetail.reqSeqID)) {
                                    tmpRetDetail.reqSeqID = p_req1944.askNumber;
                                }

                                if (StringHelper.hasAnyChar(respJSONObj.getString("RefundFee_" + i))) {
                                    tmpRetDetail.transAmt = StringHelper.amountDivide100(respJSONObj.getString("RefundFee_" + i));
                                }

                                tmpRetDetail.transState = StringHelper.joinNotEmpty("+", status, respJSONObj.getString("RefundStatus_" + i));
                                tmpRetDetail.payInfoCode = respJSONObj.getString("RefundStatus_" + i);
                            }
                        } else {
                            tmpRetDetail.respCode = "-1";
                            tmpRetDetail.respInfo = respJSONObj.getString("ReturnMsg");
                        }
                    }
                } else if (tmpStrRet[0].equals(ConnState.FAIL)) {
                    tmpRetDetail.respCode = "0";
                    tmpRetDetail.respInfo = tmpStrRet[1];
                    tmpRetDetail.reqSeqID = p_req1944.askNumber;
                    tmpRetDetail.transState = PaymentState.FAIL_Payment;
                    tmpRetDetail.payInfoCode = FailCode.E9999;
                } else {
                    tmpRetDetail.respCode = "-1";
                    tmpRetDetail.respInfo = tmpStrRet[1];
                }
            } else {
                tmpRetDetail.respCode = "0";
                tmpRetDetail.respInfo = "未找到账号: --[" + p_req1944.payAct + "]-- 商户信息";
                tmpRetDetail.reqSeqID = p_req1944.askNumber;
                tmpRetDetail.transState = PaymentState.FAIL_Payment;
                tmpRetDetail.payInfoCode = FailCode.E9981;
            }
        } catch (Exception e) {
            e.printStackTrace();

            tmpRetDetail.respCode = "-1";
            tmpRetDetail.respInfo = e.getMessage();

            WriteBankLogLn(e);
        }

        if (StringHelper.isNullOrEmpty(tmpRetDetail.reqSeqID) && "-1".equals(tmpRetDetail.respCode)) {
            tmpRetDetail.reqSeqID = p_req1944.askNumber;
        }

        retAts.writeRetDetail(tmpRetDetail);
        return retAts;
    }

    public RetAtsSingle d_190803_QrySglPay(ReqQrySingle p_req1944) throws Exception {
        RetAtsSingle retAts = new RetAtsSingle(p_req1944.reqHeader);
        RetAtsSglDetail tmpRetDetail = new RetAtsSglDetail();
        tmpRetDetail.reqSeqID = p_req1944.askNumber;
        try {
            FnGrd01Header bankHeader = new FnGrd01Header();

            bankHeader.CommandCode = "22128";

            bankHeader.CorpBankCode = getBankConfig().getMapValueByKey("corBankCodeMapping", p_req1944.payAct);
            if (StringHelper.isNullOrEmpty(bankHeader.CorpBankCode)) {
                WriteBankLogLn2("CorpBankCode为空，请配置corBankCodeMapping映射");
            }

            bankHeader.TransSeqID = getQryTransID();
            bankHeader.SourceChannel = "ATS01";

            XmlTextWriter xmlWriter = new XmlTextWriter();
            writeCommonHeader(xmlWriter, bankHeader);

            xmlWriter.writeStartElement("RealTimeSingleTransQueryReq");
            xmlWriter.writeElementString("TransNo", p_req1944.askNumber);
            xmlWriter.writeElementString("TransDate", Format.Date8Format.format(p_req1944.getBgnDateTime()));
            xmlWriter.writeEndDocument();

            String[] tmpStrRet = sendToBank(xmlWriter.toXmlString());

            if (tmpStrRet[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String tmpRetCode = tmpBkReader.getFirstText("/Root/Head/RespCode");
                    String tmpRetMsg = tmpBkReader.getFirstText("/Root/Head/RespInfo");
                    int tmpIntRespCode = -1;
                    if (!StringHelper.isNullOrEmpty(tmpRetCode)) {
                        tmpIntRespCode = Integer.parseInt(tmpRetCode);
                    }

                    if (tmpIntRespCode >= 0) {
                        tmpRetDetail.respCode = "0";
                        tmpRetDetail.reqSeqID = tmpBkReader.getFirstText("/Root/RealTimeSingleTransQueryResp/Trans/TransNo");
                        tmpRetDetail.respInfo = tmpBkReader.getFirstText("/Root/RealTimeSingleTransQueryResp/Trans/Info");
                        tmpRetDetail.transState = tmpBkReader.getFirstText("/Root/RealTimeSingleTransQueryResp/Trans/State");
                        tmpRetDetail.payInfoCode = tmpBkReader.getFirstText("/Root/RealTimeSingleTransQueryResp/Trans/InfoCode");
                        tmpRetDetail.transAmt = tmpBkReader.getFirstText("/Root/RealTimeSingleTransQueryResp/Trans/Amount");
                    } else {
                        if (StringHelper.isNullOrEmpty(tmpRetMsg)) {
                            tmpRetDetail.respInfo = "前置返回查询失败RespCode：" + tmpRetCode;
                        } else {
                            tmpRetDetail.respInfo = tmpRetMsg;
                        }
                    }
                } else {
                    tmpRetDetail.respCode = "-1";
                    tmpRetDetail.respInfo = tmpSbMsg.toString();
                }
            } else {
                tmpRetDetail.respCode = "-1";
                tmpRetDetail.respInfo = tmpStrRet[1];
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            tmpRetDetail.respCode = "-1";
            tmpRetDetail.respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }

        retAts.writeRetDetail(tmpRetDetail);
        return retAts;
    }

    @Override
    public RetAtsSingleBat d_1908BAT_SglBatPay(ReqSingleBat p_req1908BAT) throws Exception {
        return null;
    }

    @Override
    public RetAtsSingleBat d_1944BAT_QrySglBatPay(ReqQrySingleBat p_req1944BAT) throws Exception {
        return null;
    }
}
